﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using static System.Windows.Forms.LinkLabel;

namespace OxyPlotDemo
{
    public partial class MainWindow : Window
    {
        public ObservableCollection<double> Angles { get; set; }
        private double centerX = 0, centerY = 0, radius = 100;
        private int? draggedPointIndex = null;
        public AngleInputViewModel ViewModel {  get; set; }
        
        public MainWindow()
        {
            InitializeComponent();
            // 这里确保 ViewModel 被正确初始化
            ViewModel = new AngleInputViewModel();
            this.DataContext = ViewModel;
            Angles = new ObservableCollection<double>();
            InitialCircle();
        }


        private void InitialCircle() 
        {
            DrawingCanvas.Children.Clear();
            DrawCircle(centerX, centerY, radius);
            DrawPointsOnCircle();
        }

        // 绘制圆
        private void DrawCircle(double centerX, double centerY, double radius)
        {
            Ellipse circle = new Ellipse
            {
                Width = radius * 2,
                Height = radius * 2,
                Stroke = Brushes.Gray,
                StrokeThickness = 3,
                Name = ""
            };
            Canvas.SetLeft(circle, centerX - radius);
            Canvas.SetTop(circle, centerY - radius);
            DrawingCanvas.Children.Add(circle);
            Line xAxis = new Line
            {
                X1 = centerX - radius - 10,
                Y1 = centerY,
                X2 = centerX + radius + 10,
                Y2 = centerY,
                Stroke = Brushes.Black,
                StrokeThickness = 2
            };
            DrawingCanvas.Children.Add(xAxis);

            Line yAxis = new Line
            {
                X1 = centerX,
                Y1 = centerY - radius - 10,
                X2 = centerX,
                Y2 = centerY + radius + 10,
                Stroke = Brushes.Black,
                StrokeThickness = 2
            };
            DrawingCanvas.Children.Add(yAxis);
        }


        public List<Line> lines { get; set; } = new List<Line>();
        public List<Ellipse> ellipses { get; set; } = new List<Ellipse>();
        public List<TextBlock> textBlocks { get; set; } = new List<TextBlock>();
        private void UpdatePointsOnCircle(int roundedAngle, int? draggedPointIndex)
        {
            if (!draggedPointIndex.HasValue) return;
            int index = draggedPointIndex.Value;
            // 更新线的位置
            Line line = lines[index];
            // 更新点的位置
            Ellipse point = ellipses[index];
            // 更新文本的位置和内容
            TextBlock angleText = textBlocks[index];
            angleText.Text = $"{roundedAngle}°";

            // 更新旋转变换的角度
            RotateTransform rotateTransformLine = line.RenderTransform as RotateTransform;
            if (rotateTransformLine != null)
            {
                rotateTransformLine.Angle = roundedAngle;  // 更新线的旋转角度
            }

            RotateTransform rotateTransformPoint = point.RenderTransform as RotateTransform;
            if (rotateTransformPoint != null)
            {
                rotateTransformPoint.Angle = roundedAngle;  // 更新点的旋转角度
            }

            RotateTransform rotateTransformText = angleText.RenderTransform as RotateTransform;
            if (rotateTransformText != null)
            {
                rotateTransformText.Angle = roundedAngle;  // 更新文本的旋转角度
            }


        }


        // 绘制圆周上的点
        private void DrawPointsOnCircle()
        {
            lines.Clear();
            ellipses.Clear();
            textBlocks.Clear();
            var i = 0;
            foreach (var angle in Angles)
            {
                double radian = (angle - 90) * Math.PI / 180;
                double x = centerX + radius * Math.Cos(radian);
                double y = centerY + radius * Math.Sin(radian);
                double x1 = centerX ;
                double y1 = centerY - radius;
                // 创建并添加线
                Line line = new Line
                {
                    X1 = centerX,
                    Y1 = centerY,
                    X2 = x1,
                    Y2 = y1,
                    Stroke = Brushes.Black,
                    StrokeThickness = 1,
                };

                lines.Add(line);

                DrawingCanvas.Children.Add(line);

                // 创建并添加点
                Ellipse point = new Ellipse
                {
                    Width = 8,
                    Height = 8,
                    Fill = Brushes.Red,
                };
                Canvas.SetLeft(point, x1 - point.Width / 2);
                Canvas.SetTop(point, y1 - point.Height / 2);
                ellipses.Add(point);
                DrawingCanvas.Children.Add(point);

                // 创建并添加文本
                TextBlock angleText = new TextBlock
                {
                    Text = $"{angle}°",
                    Foreground = Brushes.Black,
                };
                Canvas.SetLeft(angleText, x1);
                Canvas.SetTop(angleText, y1 - 20);
                textBlocks.Add(angleText);
                DrawingCanvas.Children.Add(angleText);
                
                line.RenderTransform = new RotateTransform(angle, centerX, centerY);
                point.RenderTransform = new RotateTransform(angle, -x1 + point.Width / 2, -y1 + point.Height / 2);
                angleText.RenderTransform = new RotateTransform(angle, x1, -y1 + 20);
                i++;
            }
        }


        private void GenerateEquallySpacedAngles_Click(object sender, RoutedEventArgs e)
        {
            // 获取输入框中的值
            var divisionsText = FindName("DivisionsInput") as TextBox;
            var offsetText = FindName("OffsetInput") as TextBox;

            // 尝试解析输入的等分数量和偏移角度
            if (int.TryParse(divisionsText.Text, out int divisions) && double.TryParse(offsetText.Text, out double offset))
            {
                // 清空当前的角度集合
                Angles.Clear();

                // 根据输入的等分数量和偏移角度生成角度
                for (int i = 0; i < divisions; i++)
                {
                    double angle = offset + (i * 360.0 / divisions);
                    angle = angle % 360;  // 确保角度在 0 到 360 之间
                    angle = Math.Round(angle, 5);
                    Angles.Add(angle);  // 将计算得到的角度添加到 Angles 集合中
                }

                InitialCircle();
            }
            else
            {
                // 如果输入的值无效，弹出警告
                MessageBox.Show("请输入有效的等分数量和偏移角度！", "输入错误", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void AddCustomAngles_Click(object sender, RoutedEventArgs e)
        {
            // 清空当前的角度集合
            Angles.Clear();

            // 获取自定义角度输入框的值
            var angleInput = FindName("AngleInput") as TextBox;
            var customAngles = angleInput.Text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            // 尝试解析并添加每个自定义角度
            foreach (var angleStr in customAngles)
            {
                if (double.TryParse(angleStr.Trim(), out double angle))
                {
                    // 归一化角度到 0-360 范围
                    angle = angle % 360;
                    if (angle < 0) angle += 360; // 如果是负数，确保是正数
                    angle = Math.Round(angle, 5);
                    // 检查角度是否已经存在于 Angles 集合中
                    if (Angles.Contains(angle))
                    {
                        // 如果角度重复，弹出提示并跳过该角度
                        MessageBox.Show($"角度 {angle} 已经存在，请输入不同的角度！", "输入错误", MessageBoxButton.OK, MessageBoxImage.Warning);
                        return;  // 终止处理，避免重复角度被添加
                    }

                    // 将有效且不重复的角度添加到 Angles 集合
                    Angles.Add(angle);
                }
                else
                {
                    // 如果某个角度无效，弹出警告
                    MessageBox.Show("请输入有效的角度！", "输入错误", MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;  // 终止处理，避免无效角度被添加
                }
            }

            InitialCircle();
        }

        private int? GetNearestPointIndex(Point mousePosition)
        {
            double minDistance = double.MaxValue;
            int? nearestIndex = null;

            for (int i = 0; i < Angles.Count; i++)
            {
                double radian = (Angles[i] - 90) * Math.PI / 180;
                double x = centerX + radius * Math.Cos(radian);
                double y = centerY + radius * Math.Sin(radian);

                double distance = Math.Sqrt(Math.Pow(mousePosition.X - x, 2) + Math.Pow(mousePosition.Y - y, 2));
                if (distance < minDistance && distance < 10) // 距离小于 10 视为选中
                {
                    minDistance = distance;
                    nearestIndex = i;
                }
            }
            return nearestIndex;
        }

        // 鼠标按下时记录被拖拽的点索引
        private void DrawingCanvas_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (draggedPointIndex.HasValue)
            {
                ellipses[draggedPointIndex.Value].Fill = Brushes.Red;
                lines[draggedPointIndex.Value].Stroke = Brushes.Black;
                draggedPointIndex = null;

            }

            if (!draggedPointIndex.HasValue && e.LeftButton == MouseButtonState.Pressed )
            {
                Point mousePosition = e.GetPosition(DrawingCanvas);
                draggedPointIndex = GetNearestPointIndex(mousePosition);
                if (draggedPointIndex != null) 
                {
                    AngleSlider.Value = Angles[draggedPointIndex.Value];
                    ellipses[draggedPointIndex.Value].Fill = Brushes.Blue;
                    lines[draggedPointIndex.Value].Stroke = Brushes.Blue;
                }
            }
        }

        private DateTime lastUpdate = DateTime.MinValue;
        // 鼠标移动时更新拖拽点的角度
        private void DrawingCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed && draggedPointIndex.HasValue)
            {

                var now = DateTime.Now;
                if ((now - lastUpdate).TotalMilliseconds < 100)
                    return;
                double angle = CalAngle(new Point(0,0), e.GetPosition(DrawingCanvas));

                if (angle < 0) angle += 360;
                int roundedAngle = (int)Math.Round(angle);
                Angles[draggedPointIndex.Value] = roundedAngle;
                AngleSlider.Value = roundedAngle;
                // 只更新被拖动点相关的图形
                UpdatePointsOnCircle(roundedAngle, draggedPointIndex);
                lastUpdate = DateTime.Now;
            }
        }

        public static double CalAngle(Point center, Point p) => Math.Atan2(p.Y - center.Y, p.X - center.X) * 180 / Math.PI + 90 ;


        // 鼠标释放时清空拖拽点索引
        private void DrawingCanvas_MouseUp(object sender, MouseButtonEventArgs e)
        {
            //ellipses[draggedPointIndex.Value].Fill = Brushes.Red;
            //lines[draggedPointIndex.Value].Stroke = Brushes.Black;
            //draggedPointIndex = null;
        }


        private void EqualSpacingRadioButton_Checked(object sender, RoutedEventArgs e)
        {
            ViewModel.IsEqualSpacingModeVisible = true;  // 显示等分角度输入框
            ViewModel.IsCustomAnglesModeVisible = false; // 隐藏自定义角度输入框
        }


        private void CustomAnglesRadioButton_Checked(object sender, RoutedEventArgs e)
        {
            ViewModel.IsEqualSpacingModeVisible = false;  // 隐藏等分角度输入框
            ViewModel.IsCustomAnglesModeVisible = true;   // 显示自定义角度输入框
        }

        private void AngleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if(draggedPointIndex == null)return;
            int roundedAngle = (int)AngleSlider.Value;
            Angles[draggedPointIndex.Value] = roundedAngle;
            UpdatePointsOnCircle(roundedAngle, draggedPointIndex);
        }


    }
}

